/*
 * TITLE:	Client.h
 *
 * PURPOSE:	This file encapsulates the radio/vision client interfaces that 
 *              hide the socket interface to the vision/radio servers
 *
 * WRITTEN BY:	      James R Bruce, Scott Lenser, Michael Bowling, Brett Browning
 */
/* LICENSE: */

#ifndef __CLIENT_H__
#define __CLIENT_H__

#include <sys/time.h>
#include <sys/types.h>
#include <sys/socket.h>

#include <stdlib.h>
#include <stdio.h>
//#include <unistd.h>

#include "utils/socket.h"
#include "reality/net_vision.h"
#include "reality/net_radio.h"
//#include "reality/vision/vtypes.h"


//==== Vision/Radio  External Interface ====//

class Client {
private:
  RobotCommandMsg rcmd;
  int num_rcmd_robots;

public:
  Socket vision_s;
  // Socket radio_s;

  // intialization stuff
  Client() {
    vision_s.set(NET_VISION_PROTOCOL, NET_VISION_ACK_PERIOD);
    // radio_s.set(NET_RADIO_PROTOCOL, NET_RADIO_ACK_PERIOD);
    num_rcmd_robots = 0;
  }

  bool initialize(char *hostname, int vport = NET_VISION_PORT, int rport = NET_RADIO_PORT);
  void close();
  bool isConnected() {
    return ((vision_s.get_status() == Socket::Client));
	// && (radio_s.get_status() == Socket::Client));
  }
  void disconnect() {
    if(vision_s.get_status() == Socket::Client) vision_s.disconnect();
  }

  // Vision wrappers
  bool configure(VisionConfigMsg &msg);
  bool configure(VisionConfig &vc);
  bool sendRef(char state);
  bool moveBall(double x, double y, double vx, double vy);
  bool moveRobot(uchar team, uchar id, double x, double y, double angle);

  bool getUpdate(net_vframe &vf);

  // Radio commands
  bool enableRadio(bool en);
  bool radioControl(char ctrl);

  /*
  // function to set a command in teh command list...will not send it
  bool SetCommand(double tstamp, char team, char rid, double vx, double vy, double va, 
		  bool kick = false, bool drib = false, char priority = 1);
  bool SetCommand(double tstamp, char team, char rid, vector3d vcmd,
		  bool kick = false, bool drib = false, char priority = 1) {
    return SetCommand(tstamp, team, rid, vcmd.x, vcmd.y, vcmd.z, kick, drib, priority);
  }
  bool SetCommand(double tstamp, int team, int rid, vector3d vcmd,
		  bool kick = false, bool drib = false, char priority = 1) {
    return SetCommand(tstamp, (char) team, (char) rid, vcmd.x, vcmd.y, vcmd.z, 
		      kick, drib, priority);
  }
  */

  // bool SetHalt(double tstamp, char team, char rid, char priority = 1);
  /*
  bool SetHalt(double tstamp, int team, int rid, int priority = 1) {
    return(SetHalt(tstamp, (char) team, (char) rid, (char) priority)); }

  // set a single command and send it
  bool SendCommand(double tstamp, char team, char rid, double vx, double vy, double va, 
		   bool kick = false, bool drib = false, char priority = 1) {
    if (SetCommand(tstamp, team, rid, vx, vy, va, kick, drib, priority))
      return Send();
    return false;
  }
  bool SendCommand(double tstamp, char team, char rid, vector3d vcmd,
		   bool kick = false, bool drib = false, char priority = 1) {
    return SendCommand(tstamp, team, rid, vcmd.x, vcmd.y, vcmd.z, kick, drib, priority);
  }
  */

  bool setCommand(RobotCommand &cmd);
  bool setHalt(uchar rid);

  // send all the commands 
  bool send(int team);
};

#endif /* __CLIENT_H__ */
